package pers.sloera.leetcode.editor.cn;

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

/**
 * Lisp 语法解析
 *
 * @author sloera
 * @date 2022-07-06 21:43:17
 */
class ParseLispExpression {
    public static void main(String[] args) {
        Solution solution = new ParseLispExpression().new Solution();
        System.out.println(solution.evaluate("(let x 2 (mult x (let x 3 y 4 (add x y))))"));
    }

    //leetcode submit region begin(Prohibit modification and deletion)
    class Solution {
        Map<String, Stack<Integer>> variableMap = new HashMap<>();

        public int evaluate(String expression) {
            return evaluate(expression, 0, expression.length() - 1, new HashMap<String, Integer>());
        }

        private int evaluate(String expression, int start, int end, Map<String, Integer> varibales) {
            if (expression.length() == 1) {
                return Integer.parseInt(expression);
            }
            if (expression.charAt(0) == '(') {
                int rightIndex = findRightIndex(expression, start);
                String subExpression = expression.substring(start + 1, rightIndex - 1);
                // 计算子表达式
                String remainExpression = expression.replace("(" + subExpression + ")", String.valueOf(evaluate(subExpression, 0, rightIndex - start, varibales)));
                return evaluate(remainExpression, start, end - rightIndex + start, varibales);
            }
            HashMap<String, Integer> innerVariables = new HashMap<>(varibales);
            if (expression.startsWith("let")) {
                int left = start + 4;
                setVariables(expression, varibales, left);
            } else if (expression.startsWith("add")) {

            } else if (expression.startsWith("mult")) {

            } else {
                return Integer.parseInt(expression);
            }
            return 0;
        }

        // 设置let的变量
        private void setVariables(String expression, Map<String, Integer> varibales, int left) {
            while (true) {
                int right = left;
                String key;
                right = getRightIndex(expression, right);
                key = expression.substring(left, right - 1);
                // 跳过空格
                left = ++right;
                int value;
                if (expression.charAt(right + 1) == '(') {
                    int rightIndex = findRightIndex(expression, right + 1);
                    String valueSub = expression.substring(right + 1, rightIndex);
                    value = evaluate(valueSub, right + 1, rightIndex, varibales);
                } else {
                    right = getRightIndex(expression, right);
                    value = Integer.parseInt(expression.substring(left, right - 1));
                }
                varibales.put(key, value);
            }
        }

        private int getRightIndex(String expression, int right) {
            while (expression.charAt(++right) != ' ') {
            }
            return right;
        }

        private String parseLet(String expression, int start, int end) {
            char[] chars = expression.toCharArray();
            int braceCount = 0;
            for (int i = start; i < end; i++) {
                if (chars[i] == '(') {
                    braceCount++;
                    continue;
                }
            }
            return null;
        }

        private int findRightIndex(String expression, int start) {
            char[] chars = expression.toCharArray();
            int braceCount = 1;
            int i = start + 1;
            for (; i < chars.length && braceCount > 0; i++) {
                if (chars[i] == '(') {
                    braceCount++;
                } else if (chars[i] == ')') {
                    braceCount--;
                }
            }
            return i;
        }
    }
    //leetcode submit region end(Prohibit modification and deletion)

}
